<?php
namespace tp5_lib\user\logic;

use think\Request;
use tp5_lib\user\model\UserModel;
use tp5_lib\user\model\MobileCodeModel;
use think\Db;
use think\Model;
use think\facade\Session;

/**
 * 用户逻辑
 * @property UserModel $model 用户模型
 * @property MobileCodeModel $code 手机验证码模型
 */
class UserLogic
{
    public function __get($name)
    {
        if($name === "model"){
            if(empty($this->_model)){
                $this->_model=new UserModel();
            }
            return $this->_model;
        }
        elseif($name === "code"){
            if(empty($this->_code)){
                $this->_code=new MobileCodeModel();
            }
            return $this->_code;
        }
    }
    protected $error="";
    public function getError()
    {
        return $this->error;
    }
    public function ip()
    {
        $reqest=new Request();
        return $reqest->ip();
    }
    /**
     * 普通注册
     */
    public function register($username,$password,$extend)
    {
        if($this->model->db()->where(["username"=>$username])->find()){
            $this->error="用户名已被占用";
            return false;
        }
        $secret=rand(0,999999);
        $password=$this->model->encrypt($password,$secret);
        $extend["username"]=$username;
        $extend["password"]=$password;
        $extend["secret"]=$secret;
        return $this->doRegister($extend);
    }
    /**
     * 手机号注册
     */
    public function mobileRegister($mobile,$code,$password)
    {
        if(!$this->code->check($mobile,$code,"register")){
            $this->error=$this->code->getError();
            return false;
        }
        if($this->model->db()->where(["mobile"=>$mobile])->find()){
            $this->error="手机号已被占用";
            return false;
        }
        $secret=rand(0,999999);
        $password=$this->model->encrypt($password,$secret);
        $data=[
            "username"=>"m_".$mobile,
            "mobile"=>$mobile,
            "password"=>$password,
            "secret"=>$secret,
        ];
        return $this->doRegister($data);
    }
    /**
     * 快速注册
     */
    public function quickRegister($mobile,$code)
    {
        if(!$this->code->check($mobile,$code,"register")){
            $this->error=$this->code->getError();
            return false;
        }
        if($this->model->db()->where(["mobile"=>$mobile])->find()){
            $this->error="手机号已被占用";
            return false;
        }
        $data=[
            "username"=>"q_".$mobile,
            "mobile"=>$mobile,
            "password"=>"",
            "secret"=>"",
        ];
        return $this->doRegister($data);
    }
    public function doRegister($data)
    {
        $module=new UserModule("user");
        $config = $module->read("user");
        foreach($config["register_append"] as $cb){
            $data=call_user_func($cb,$data);
        }
        $uid=$this->model->register($data,Session::id(),$this->ip());
        if(!$uid){
            return false;
        }
        $record = $this->model->where(["id"=>$uid])->find()->toArray();
        Session::set("user",$record);
        return $record;
    }
    /**
     * 普通登录
     * @param string $name id/username/mobile
     */
    public function login($name,$password)
    {
        $user=$this->model->findUser($name);
        if(!$user){
            $this->error=$this->model->getError();
            return false;
        }
        if(empty($user["password"])){
            $this->error="尚未设置密码，请使用其他方式登录";
            return false;
        }
        $password=$this->model->encrypt($password,$user["secret"]);
        if($user["password"]!==$password){
            $this->error="密码错误";
            return false;
        }
        return $this->doLogin($user["id"]);
    }
    /**
     * 短信登录
     */
    public function smsLogin($mobile,$code)
    {
        if(!$this->code->check($mobile,$code,"login")){
            $this->error=$this->code->getError();
            return false;
        }
        $user=$this->model->where(["mobile"=>$mobile])->find();
        if(!$user){
            $this->error="手机号不存在";
            return false;
        }
        return $this->doLogin($user["id"]);
    }
    public function doLogin($uid)
    {
        $this->model->login($uid,Session::id(),$this->ip());
        $record = $this->model->where(["id"=>$uid])->find()->toArray();

        Session::set("user",$record);

        $module=new UserModule("user");
        $config = $module->read("user");
        foreach($config["login_call"] as $cb){
            call_user_func($cb,$record);
        }

        return $record;
    }
    public function getbackPassword($name,$code,$new)
    {
        $user=$this->model->findUser($name);
        if(!$user){
            $this->error=$this->model->getError();
            return false;
        }
        $mobile=$user["mobile"];
        if(!$this->code->check($mobile,$code,"findback")){
            $this->error=$this->code->getError();
            return false;
        }
        return $this->doResetPassword($user,$new);
    }
    public function resetPassword($user,$old,$new)
    {
        if($user["password"] !== $this->model->encrypt($old,$user["secret"])){
            $this->error="密码错误";
            return false;
        }
        return $this->doResetPassword($user,$new);
    }
    protected function doResetPassword($user,$new)
    {
        $secret=rand(0,999999);
        $password=$this->model->encrypt($new,$secret);
        $update=[
            "password"=>$password,
            "secret"=>$secret,
        ];
        if(!$this->model->db()->where(["id"=>$user["id"]])->update($update)){
            $this->error="修改用户密码失败";
            return false;
        };
        if($user instanceof Model ){
            $user=$user->toArray();
        }
        $user=array_merge($user,$update);
        Session::set("user",$user);
        return $user;
    }
    public function bindMobile($user,$mobile,$code)
    {
        if(!$this->code->check($mobile,$code,"bind_mobile")){
            $this->error=$this->code->getError();
            return false;
        }
        if(!$this->model->save(["mobile"=>$mobile],["id"=>$user["id"]])){
            $this->error=$this->model->getError();
            return false;
        }
        $user["mobile"]=$mobile;
        Session::set("user",$user);
        return $user;
    }
    public function updateProfile($user,$profile)
    {
        if(!$this->model->updateProfile($user["id"],$profile)){
            $this->error=$this->model->getError();
            return false;
        }
        $user=array_merge($user,$profile);
        Session::set("user",$user);
        return $user;
    }
    /**
     * 管理员删除用户
     */
    public function remove($uid)
    {
        $user=$this->model->where(["id"=>$uid])->find();
        Session::ban($user["token"]);
        return $this->doRemove($uid);
    }
    /**
     * 用户注销
     */
    public function discharge($uid)
    {
        Session::clear("user");
        return $this->doRemove($uid);
    }
    protected function doRemove($uid)
    {
        if($this->model->db()->where(["id"=>$uid])->delete()){
            $this->error="删除失败";
            return false;
        }
        /** @todo 删除所有相关表中的关联记录 */
        return true;
    }
    /**
     * 刷新当前用户信息
     */
    public function refresh()
    {
        if(!$user = Session::get("user")) return false;
        if(!$user = $this->model->db()->where("id",$user["id"])->find()){
            Session::clear("user");
            return false;
        }
        return $user;
    }
}
